/*
class Singleton{
    private static Singleton instance=new Singleton;

    public static Singleton getInstance() {
        return instance;
    }
    private Singleton(){}
}

*/

/*class SingletonLazy{
    private static volatile SingletonLazy instance=null;
    private static Object locker=new Object();
    public static SingletonLazy getInstance() {
        if (instance==null){
            synchronized (locker){
                if (instance==null){
                    instance=new SingletonLazy();
                }
            }
        }
        return instance;
    }

    private SingletonLazy(){}
}*/


import java.util.PriorityQueue;
/*

class MyTimertask implements Comparable<MyTimertask>{
    private long time;
    private Runnable runnable;

    public MyTimertask(Runnable runnable,long delay){
        this.time=System.currentTimeMillis();
        this.runnable=runnable;
    }


    public long getTime() {
        return time;
    }

    public void run(){
        runnable.run();
    }

    @Override
    public int compareTo(MyTimertask o) {
        return (int) (this.time-o.time);
    }
}
*/



/*class MyTimer{
    private Thread t;
    private PriorityQueue<MyTimertask> queue=new PriorityQueue();
    private Object locker=new Object();

    public void schdeule(Runnable runnable,long delay){
        synchronized (locker){
            MyTimertask task=new MyTimertask(runnable,delay);
            queue.offer(task);
            locker.notify();
        }
    }

    public MyTimer(){
        t=new Thread(()->{
         synchronized (locker){
             while (true){
                 while (queue.isEmpty()){
                     try {
                         locker.wait();
                     } catch (InterruptedException e) {
                         throw new RuntimeException(e);
                     }
                 }
                 MyTimertask curtask=queue.peek();
                 if (System.currentTimeMillis()>=curtask.getTime()){
                     queue.poll();
                     curtask.run();
                 }else {
                     try {
                         locker.wait(curtask.getTime()-System.currentTimeMillis());
                     } catch (InterruptedException e) {
                         throw new RuntimeException(e);
                     }
                 }
             }
         }
        });
        t.start();
    }
}*/


class MyBlockingQueue{
    private String[] elems;

    public MyBlockingQueue(int capcity){
        this.elems=new String[capcity];
    }

    private int head;
    private int tail;
    private int size;

    private Object locker=new Object();

    public void put(String string) throws InterruptedException {
       synchronized (locker){
           while (size==elems.length){
               //
                locker.wait();
           }
           elems[tail]=string;
           tail++;
           if (tail==elems.length){
               tail=0;
           }
           size++;
           locker.notify();
       }
    }

    public String take() throws InterruptedException {
        String elem=null;
        synchronized (locker){
            while (size==0){
                locker.wait();
            }
            elem=elems[head];
            head++;
            if (head==elems.length){
                head=0;
            }
            size--;
            locker.notify();
        }
        return elem;

    }
}










public class Test {
    public static void main(String[] args) {
        //Singleton.getInstance();
        //SingletonLazy.getInstance();

       /* MyTimer timer=new MyTimer();
        timer.schdeule(()->{
            System.out.println("第一次");
        },2000);*/




        MyBlockingQueue queue=new MyBlockingQueue(10);

        Thread  t1=new Thread(()->{
            int i=0;
           while (true){
               System.out.println("生产元素"+i);
               i++;
               try {
                   queue.put(i+" ");
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
           }
        });

        Thread t2=new Thread(()->{
            int i=0;
            while (true){
                System.out.println("消费元素"+i);
                i++;
                try {
                    Thread.sleep(1000);
                    queue.take();

                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t1.start();
        t2.start();
    }
}
